{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Software Engineering\n",
    "\n",
    "Software engineering was first introduced in the 1960s in an effort to treat more rigorously the often frustrating task of designing and developing computer programs. It was around this time that the computer community became increasingly worried about the fact that software projects were typically over budget and behind schedule. \n",
    "\n",
    "The term **software crisis（软件危机）** came to signify that software development was the bottleneck in the advancement of computer technology.\n",
    "\n",
    "## 1 Introduction to Software Engineering\n",
    "\n",
    "\n",
    "### 1.1 Software Characteristics\n",
    "\n",
    "From an engineering viewpoint a software system is a product that serves a function.\n",
    "\n",
    "However, \n",
    "\n",
    "**1 A program can be changed**：\n",
    "\n",
    "one unique attribute makes a computer program much different from a bridge or an airplane: a program can be changed. This malleability of software is both an advantage and a danger. \n",
    "  * An advantage because it is often possible to correct an error in a program much easier than it would be to fix a defect in an airplane or automobile.\n",
    "  \n",
    "  *  A danger because a modification in a program can introduce unanticipated side effects that may impair the functionality of those components that were executing correctly before the change.\n",
    "\n",
    "**2. The most important element of the Software product cost is the human effort in design and development**\n",
    "\n",
    "The another notable characteristic of programs relate to the type of `resources necessary for their creation`. \n",
    "\n",
    "A software product is basically an intellectual commodity. The principal resource necessary for producing it is `human intelligence`. \n",
    "\n",
    "The actual manufacturing of programs is `simple and inexpensive` compared to its design, coding, testing, and documenting. \n",
    "\n",
    "This contrasts with many other engineered products in which the resources used in producing it are a substantial part of the product’s\n",
    "final cost. For example, a considerable portion of the price of a new automobile represents the cost of manufacturing it, while a less significant part goes to pay for the engineering costs of design and development.\n",
    "\n",
    "In the case of a typical computer program the proportions are reversed. The most important element of the product cost is the human effort in design and development while the cost of manufacturing is proportionally insignificant.\n",
    "\n",
    "### 1.2 Software Qualities\n",
    "\n",
    "An engineered product is usually associated with a list of qualities that define its usability. \n",
    "\n",
    "For example, in performing its functions a bridge supports a predetermined weight and withstands a given wind force. An airplane is capable of transporting a\n",
    "specific load, at a certain speed and altitude. \n",
    "\n",
    "By the same token, a software product is associated with a given set of qualities that define its functionality. \n",
    "\n",
    "The principal goals of software engineering is to define, specify, and measure software qualities and to describe the principles that can be applied to achieve them.\n",
    "\n",
    "The classification of software qualities can be based on the relation with the software product. In this sense we can speak of qualities desirable to the user,to the developer, or to the manager. \n",
    "\n",
    "The Table lists some qualities according to this classification.\n",
    "\n",
    "![qualities](./img/se/se-quality.jpg)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3  Principles of Software Engineering"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We started this chapter on the assumption that software development is a `creative activity` and that programming is `not an exact science`. \n",
    "\n",
    "From this point of view even the term software engineering may be considered unsuitable since we could preferably\n",
    "speak of `software development technique`, which term does not imply the rigor of a formal engineering approach.\n",
    "\n",
    "In our opinion it is a `mistake` to assume that programs can be mechanically generated by some `mechanical methodology`, no matter\n",
    "how sophisticated. \n",
    "\n",
    "When software engineering falls short of producing the expected results it is because we `over-stressed the scientific and technical aspects` of program development over those that are `artistic or aesthetic` in nature or that depend on talent, personal endowments, or know-how. \n",
    "\n",
    "Nevertheless, as there is `technique in art`, there is `technique in program development`.\n",
    "\n",
    "Software engineering is the `conventional` name that `groups` the technical and scientific aspects of program development.\n",
    "\n",
    "\n",
    ">**Software Engineering** is **a systematic approach** to the design, development, operation, and maintenance of a software system.\n",
    ">\n",
    ">* 软件工程是设计、开发、操作和维护软件系统的系统化方法。\n",
    "\n",
    "\n",
    "**Smaller software projects** usually take place within the constraints of a limited budget. Often financial resources do not extend to hiring trained software project managers or specialists in the field of software engineering. \n",
    "\n",
    "The person in charge of the project usually wears many hats, including that of project manager and software engineer. In fact, it is not unusual that the project manager/engineer is also part-time designer, programmer, tester, and documentation specialist. \n",
    "\n",
    "What this all means is that the formality and rigor used in engineering a major project may not apply to one of lesser proportions. In other words, the strictness and rigidity of software engineering principles may have to be scaled down to accommodate the smaller projects.\n",
    "\n",
    "In this sense we must distinguish between `principles, techniques, and tools` of software engineering. \n",
    "\n",
    "**Principles** are general guidelines that are applicable at any stage of the program production process. They are the abstract statements that describe desirable properties, but that are of little use in practical software development.\n",
    "\n",
    "For example, the principle that encourages high program reliability does `not tell us how to` make a program reliable. \n",
    "\n",
    "**Techniques or methods** refer to `a particular approach` to solving a problem and help ensure that a product will have the desirable\n",
    "properties.\n",
    "\n",
    "**Tools** are specific resources that are used in implementing a particular technique. \n",
    "\n",
    "In this case we may state as a principle that floating-point numbers are a desirable format for representing decimals in a digital machine. Also that the floating-point techniques described in the ANSI standard 754 are suitable for our application\n",
    "and should be followed. Finally, that a particular library of floating-point routines, which complies with ANSI 754, would be an adequate tool for implementing the mathematical functions required in our application.\n",
    "\n",
    "The Figure graphically shows the relationship between these three elements.\n",
    "\n",
    "![](./img/se/se-ptt.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.4 Objectives of Software Engineering:\n",
    "\n",
    "1. Maintainability\n",
    " \n",
    "  * It should be feasible for the software to evolve to meet changing requirements.\n",
    "\n",
    "2. Correctness \n",
    " \n",
    "  * A software product is correct, if the different requirements as specified in the SRS document have been correctly implemented.\n",
    "\n",
    "3. Reusability \n",
    " \n",
    "  * A software product has good reusability, if the different modules of the product can easily be reused to develop new products.\n",
    "\n",
    "4. Testability \n",
    " \n",
    "  * Here software facilitates both the establishment of test criteria and the evaluation of the software with respect to those criteria.\n",
    "\n",
    "5. Reliability \n",
    " \n",
    "  * It is an attribute of software quality. The extent to which a program can be expected to perform its desired function, over an arbitrary time period.\n",
    "\n",
    "6. Portability \n",
    "   * In this case, software can be transferred from one computer system or environment to another.\n",
    "\n",
    "7. Adaptability –\n",
    "   * In this case, software allows differing system constraints and user needs to be satisfied by making changes to the software."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 Software Engineering Paradigms\n",
    "\n",
    "Computer scientists refer to the process of planning and organizing a program as software development. \n",
    "\n",
    "It includes project planning, systems and requirements analysis, data structure design, algorithm selection and evaluation, coding,\n",
    "estimation of program correctness, and maintenance procedures.\n",
    "\n",
    "There are several paradigms to software development.\n",
    "\n",
    "Three of these paradigms have been extensively discussed in the literature:\n",
    "\n",
    "* the waterfall model(瀑布模型), the prototype methods(原型方法), and the spiral model(螺旋模式)\n",
    "\n",
    "### 2.1 Waterfall Model\n",
    "\n",
    "This classical Waterfall Model of a software engineering project is based on the notion of a system life-cycle.\n",
    "\n",
    "The waterfall model consists of several phases shown in the Figure.\n",
    "\n",
    "As you can see, the figure resembles a waterfall, in which the results of each phase flow **down** to the next. \n",
    "\n",
    "![waterfall model](./img/se/waterfall.jpg)\n",
    "\n",
    "**1 The specification phase(规范定义阶段）** consists of `a requirements gathering process` through analysis and systems engineering.\n",
    "\n",
    "Whenever the project must interface with existing software or hardware elements the specification phase must include a systems requirements definition. \n",
    "\n",
    "During this phase customer and developer work very closely: the customer provides the requirements and the developer reflects these requirements in a formal specification that is, in turn, reviewed by the customer. \n",
    "\n",
    "The requirements/specification cycles continue until both parties agree that the project has been clearly and unambiguously defined.\n",
    "\n",
    ">The programmers determine **what the program** will do. \n",
    ">\n",
    ">This is a process of clarifying the **specifications（规范说明书)** for the problem\n",
    "\n",
    "\n",
    "**2 The design phase(设计阶段)**  on four elements: data structures, program architecture, procedures, and interfaces（数据结构，程序架构，过程和接口).\n",
    "\n",
    "The design stage is often the most critical and difficult one. \n",
    "\n",
    ">The programmers determine **how the program** will do its task\n",
    "\n",
    "**3 The coding phase(编码阶段)**: The programmers write the program,then convert the design into a machine-executable product.\n",
    "\n",
    "**4 The verification phase(测试阶段）** Once the code executes in a machine it must be evaluated for correctness. This means that we must ascertain that it meets the requirements developed during the specifications phase and that it is free from defects. \n",
    "\n",
    "Although this phase is sometimes associated with debugging, it should also include all formal and experimental verifications of program correctness\n",
    "\n",
    "**5 Maintenance phase（维护阶段)**—Programs usually have a long life; a life span of 5 to 15 years is common for software. \n",
    "\n",
    "During this time, requirements change, errors are detected, and minor or major modifications are made.\n",
    "\n",
    "Maintenance procedures require revisiting all the stages of the software life-cycle, as depicted by the dotted arrow in the above Figure "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A mistake detected in one phase often requires the developer to **back up** and redo some of the work in the **previous** phase. \n",
    "\n",
    "Modifications made during maintenance also require backing up to earlier phases. \n",
    "\n",
    "Taken together, these phases are also called **the software development life cycle（软件生命周期）**.\n",
    "\n",
    ">软件生命周期(Software Life Cycle)是软件的产生直到报废或停止使用的生命周期\n",
    "\n",
    "\n",
    "Although the diagram depicts distinct phases, this does not mean that developers must analyze and design a complete system before coding it.\n",
    "\n",
    "Modern software development is usually **incremental(增量)** and **iterative(迭代)**. \n",
    "\n",
    "* This means that analysis(specification) and design may produce a rough `draft, skeletal` version, or **prototype** of a system for coding, and then back up to earlier phases to fill in more details after some testing. \n",
    "\n",
    "Programs rarely work as hoped the first time they are run; hence, they should be subjected to extensive and careful **testing**. \n",
    "\n",
    "Many people think that testing is an activity that applies only to the coding(implementation) and verification(Integration) phases; however, you should scrutinize the outputs of each phase carefully.\n",
    "\n",
    "* Keep in mind that mistakes found **early** are much less expensive to correct than those found late. \n",
    "\n",
    "The Figure illustrates some relative costs of repairing mistakes when found in different phases. These are not just financial costs but also costs in time and effort.\n",
    "\n",
    "![costs_mistakes](./img/se/costs_mistakes.jpg)\n",
    "\n",
    "Keep in mind that the cost of developing software is not spread equally over the phases.The percentages shown in the Figure are typical.\n",
    "\n",
    "![percentage_costs](./img/se/percentage_costs.jpg)\n",
    "\n",
    "You might think that  coding(implementation) takes the most time and therefore costs the most.However, as you can see in the Figure, maintenance is the most expensive part of software development. \n",
    "\n",
    "**The cost of maintenance can be reduced by careful analysis, design, and implementation.**\n",
    "\n",
    "You should remember two points:\n",
    "\n",
    "1. There is **more** to software development than `writing code`.\n",
    "\n",
    "2. If you want to reduce the overall cost of software development, **write programs that are easy to maintain**. This requires thorough analysis, careful design, and a good coding style. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2 Prototyping\n",
    "\n",
    "Many software development projects are of an **experimental or speculative** nature.\n",
    "\n",
    "Consider the following examples:\n",
    "\n",
    "*  A research group wishes to determine **if it is possible**  to develop an expert system that uses data obtained by remote-sensing satellites in order determine pollution levels in the lakes and streams of the United States.\n",
    "\n",
    "*  An entrepreneur wishes to determine **if it is feasible** to develop a word processing program in which the user is equipped with foot pedals that activate some of the program functions.\n",
    "\n",
    "In either of these cases we can see that the software development project can **hardly be stated a priori**. \n",
    "\n",
    "The objectives are described so generally that it is **difficult to define specific program requirements** that could serve as a base for a detailed design. \n",
    "\n",
    "In both cases, as well as in many others in which `an initial detailed design is not possible or practical`, a **prototyping approach** could be a feasible alternative.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In prototyping the developer is able to create **a model of the software.** \n",
    "\n",
    "* This model can later be used to better `define the final product` or to `ascertain its feasibility`. \n",
    "\n",
    "The prototype can be\n",
    "\n",
    "* `a simple paper model` of the software, which can be produced with little or no coding, \n",
    "\n",
    "* `a working prototype` that implements a subset of the program functions, or\n",
    "\n",
    "* `a complete program` in which some functions are not implemented."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The purpose of the prototype is to allow both customer and developer to `make decisions regarding the feasibility and practicality` of the project, and, if judged feasible and practical, to better define the final product.\n",
    "\n",
    "Prototyping is often depicted as a development cycle with the sequence of steps shown in the Figure\n",
    "\n",
    "![](./img/se/prototypingmodel.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Prototype development\n",
    "\n",
    "* **begins** by collecting `requirements and specifications`.\n",
    "\n",
    "Then\n",
    "\n",
    "* the prototype is **designed**, usually by following an **abbreviated(缩略) process** which produces results quicker than conventional program design procedures. \n",
    "\n",
    "* The prototype is **built**, also shortening the development processes by **skipping all processing steps** that are not strictly necessary for the purpose at hand. \n",
    "\n",
    "The prototype is finally `evaluated`, first by the developer and later by the customer. \n",
    "\n",
    "If necessary, it is further `refined` and tuned in an `iterative` cycle. The finished prototype is used to further define the final software product."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 Spiral Model\n",
    "\n",
    "This model, first suggested by Barry W. Boehm in 1988(巴利·玻姆), proposes to merge the best features of the life-cycle and the prototyping paradigm with the principle of **incremental** development\n",
    "\n",
    "The Figure shows a spiral progression through four different stages.\n",
    "\n",
    "![Spiral Model](./img/se/spiralmodel.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that the drawing in the above Figure is meant as a **general** illustration of the method and is not be interpreted literally.\n",
    "\n",
    "For example, the number of cycles around the spiral will `vary from project to project`\n",
    "\n",
    "unique feature of the spiral model is the introduction of a **risk analysis stage**, which culminates in a `go or no-go decision` at the conclusion of each development cycle. \n",
    "\n",
    "However, this  risk analysis phase is also its most **controversial** feature.\n",
    "\n",
    "In the first place, risk analysis requires a particular expertise, and is trivialized when performed by un-trained personnel.\n",
    "\n",
    "In fact, the risk analysis phase is undesirable if it can lead to invalid interpretation of results.\n",
    "\n",
    "In addition, customers often believe that they performed a risk analysis of the project before deciding to undertake it, and that\n",
    "further consideration of this matter is unnecessary. \n",
    "\n",
    "Furthermore, the possibility that at the conclusion of each development cycle the entire project could be scrapped by a no-go decision may lead to apprehensions on the part of the customer.\n",
    "\n",
    "On the other hand, if the difficulties and perils associated with the risk analysis phase can be conjured, then the spiral model constitutes **the most satisfactory paradigm for the development of large software systems**. \n",
    "\n",
    "The **incremental** development approach proposed by this model, with its repeated **prototyping and riske valuation** phases, provides a **realistic** framework for program development. \n",
    "\n",
    "Both customer and developer have repeated opportunities in which to identify possible defects and shortcomings and make the necessary adjustments. \n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.4 A Pragmatic Approach\n",
    "\n",
    "The practicing software developer must decide, in each case, which model or combinations of models are most suitable to the project at hand.\n",
    "\n",
    "The decision is often based on **practical** risks and limitations rather than on theoretical applicability. \n",
    "\n",
    "For example, a developer may consider that the most adequate paradigm is the prototyping model, but a substantial risk that the customer will misinterpret the results advises against its use.\n",
    "\n",
    "In another case a project may fit quite well within the spiral model but the fact that personnel trained in risk analysis will not be available suggests a modification of the paradigm or the adoption of the more conventional waterfall model.\n",
    "\n",
    "A wise man once said: **“All systems and no system: behold the best system.”**\n",
    "\n",
    "This maxim is quite applicable to the various software engineering paradigms mentioned in the preceding sections, in particular when they concern smaller projects in which development time and resources are limited. \n",
    "\n",
    "The most common scenario is a combination of paradigms.\n",
    "\n",
    "Often the most useful one is a spiral model. Since the spiral model is in itself a combination of the waterfall and the prototyping model, all of the mentioned paradigms will actually be used.\n",
    "\n",
    "### 2.5  `Concurrent` Documentation\n",
    "\n",
    "One of the **most important lessons** of software engineering refers to the need for `adequate and rigorous project documentation`. \n",
    "\n",
    "* By the same token, the **most notable** difference between a correctly engineered development project and a haphazard effort\n",
    "is the **documentation**.\n",
    "\n",
    "Too often the tendency has been to consider program documentation as a `secondary` problem, one that can be addressed once the project\n",
    "is finished.\n",
    "\n",
    "This tendency is probably traceable to the same human fallacy that makes some programmers believe that `comments` can be inserted into the code **after** the programming has concluded. \n",
    "\n",
    "As `writing comments` is part of the `chore` of programming,`documentation` is part of the task of program `development`. \n",
    "\n",
    "* Either one **cannot** be approached as an **afterthought**, at risk of writing spaghetti code or of developing undecipherable projects.\n",
    "\n",
    "It is only by realizing that documentation is one of the `fundamental` results of a development project, and that it `should never be an afterthought` at project conclusion time, that we can invalidate these argument\n",
    "\n",
    "In regards to software project development the following types of documentation can be clearly identified:\n",
    "\n",
    "1. Written `reports` that `mark` the `conclusion` of a phase of the development cycle.\n",
    "\n",
    "  * These documents are sometimes called the deliverables(可交付成果), since they are often presented to the client as each development phases concludes.\n",
    "\n",
    "  * Typical deliverables are the feasibility study, the analysis and requirements document, and the detailed design document.\n",
    "\n",
    "\n",
    "2. User manuals and training guides, which can be printed or online.\n",
    "\n",
    "3. Operations documents, more often found in large computer environments, include run-time schedules, input and output forms and media, delivery, routing, and distribution charts, data file specifications, update schedules, recovery procedures, and security controls.\n",
    "\n",
    "4. The project scrapbook is used to **collect**  memos, schedules, meeting minutes, and other communications generated during the project\n",
    "\n",
    "The following are undeniable advantages of **concurrently documenting** the development project:\n",
    "\n",
    "1. A well-documented project is better able to resist personnel changes since new programmers can catch up by studying the project documents.\n",
    "\n",
    "2. Documentation can serve as a management tool by requiring that each development stage conclude in a document, which must be approved before the next stage can proceed.\n",
    "\n",
    "3. **Concurrent documentation** establishes a project history and can serve, among other things, as a progress report. Documents can be used as scheduling landmarks and therefore serve to measure and evaluate project progress\n",
    "\n",
    "The **most important principle** of project documentation is that of **concurrency**. \n",
    "\n",
    "Documentation must be a substantial part of the development effort and must take place **simultaneously** with each development phase. \n",
    "\n",
    "At the same time, documentation is often the development activity most easily postponed or even sacrificed. When time is running short it is tempting to defer documentation.\n",
    "\n",
    "At this point the project manager must be aware that when \n",
    "\n",
    "* `documentation loses its concurrency it also loses a great portion of its usefulness`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 The Recommended Practices for Scientific Computing\n",
    "\n",
    "Greg Wilson, Co-founder of Software Carpentry \n",
    "\n",
    "* [Best Practices for Scientific Computing](https://journals.plos.org/plosbiology/article?id=10.1371/journal.pbio.1001745)\n",
    "\n",
    "* [Good enough practices in scientific computing](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1005510)\n",
    "\n",
    "* [Ten simple rules for making research software more robust](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1005412)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div id=\"section1\" class=\"section toc-section\"><a id=\"s1a\" name=\"s1a\" class=\"link-target\" title=\"Box 1. Summary of Best Practices\"></a>\n",
    "<h3>3.1 Best Practices for Scientific Computing</h3>\n",
    "\n",
    "\n",
    "<ol class=\"order\">\n",
    "\n",
    "<li>Write programs for people, not computers.\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>A program should not require its readers to hold more than a handful of facts in memory at once.</li>\n",
    "\n",
    "<li>Make names consistent, distinctive, and meaningful.</li>\n",
    "\n",
    "<li>Make code style and formatting consistent.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Let the computer do the work.\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Make the computer repeat tasks.</li>\n",
    "\n",
    "<li>Save recent commands in a file for re-use.</li>\n",
    "\n",
    "<li>Use a build tool to automate workflows.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Make incremental changes.\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Work in small steps with frequent feedback and course correction.</li>\n",
    "\n",
    "<li>Use a version control system.</li>\n",
    "\n",
    "<li>Put everything that has been created manually in version control.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Don't repeat yourself (or others).\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Every piece of data must have a single authoritative representation in the system.</li>\n",
    "\n",
    "<li>Modularize code rather than copying and pasting.</li>\n",
    "\n",
    "<li>Re-use code instead of rewriting it.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Plan for mistakes.\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Add assertions to programs to check their operation.</li>\n",
    "\n",
    "<li>Use an off-the-shelf unit testing library.</li>\n",
    "\n",
    "<li>Turn bugs into test cases.</li>\n",
    "\n",
    "<li>Use a symbolic debugger.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Optimize software only after it works correctly.\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Use a profiler to identify bottlenecks.</li>\n",
    "\n",
    "<li>Write code in the highest-level language possible.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Document design and purpose, not mechanics.\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Document interfaces and reasons, not implementations.</li>\n",
    "\n",
    "<li>Refactor code in preference to explaining how it works.</li>\n",
    "\n",
    "<li>Embed the documentation for a piece of software in that software.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Collaborate.\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Use pre-merge code reviews.</li>\n",
    "\n",
    "<li>Use pair programming when bringing someone new up to speed and when tackling particularly tricky problems.</li>\n",
    "\n",
    "<li>Use an issue tracking tool.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "</ol></div>\n",
    "</div></div>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div id=\"section1\" class=\"section toc-section\"><a id=\"sec003\" name=\"sec003\" class=\"link-target\" title=\"Box 1. Summary of practices\"></a>\n",
    "<h3>3.2 Good enough practices in scientific computing</h3>\n",
    "\n",
    "\n",
    "<ol class=\"order\">\n",
    "\n",
    "<li>Data management\n",
    "\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Save the raw data.</li>\n",
    "\n",
    "<li>Ensure that raw data are backed up in more than one location.</li>\n",
    "\n",
    "<li>Create the data you wish to see in the world.</li>\n",
    "\n",
    "<li>Create analysis-friendly data.</li>\n",
    "\n",
    "<li>Record all the steps used to process data.</li>\n",
    "\n",
    "<li>Anticipate the need to use multiple tables, and use a unique identifier for every record.</li>\n",
    "\n",
    "<li>Submit data to a reputable DOI-issuing repository so that others can access and cite it.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Software\n",
    "\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Place a brief explanatory comment at the start of every program.</li>\n",
    "\n",
    "<li>Decompose programs into functions.</li>\n",
    "\n",
    "<li>Be ruthless about eliminating duplication.</li>\n",
    "\n",
    "<li>Always search for well-maintained software libraries that do what you need.</li>\n",
    "\n",
    "<li>Test libraries before relying on them.</li>\n",
    "\n",
    "<li>Give functions and variables meaningful names.</li>\n",
    "\n",
    "<li>Make dependencies and requirements explicit.</li>\n",
    "\n",
    "<li>Do not comment and uncomment sections of code to control a program's behavior.</li>\n",
    "\n",
    "<li>Provide a simple example or test data set.</li>\n",
    "\n",
    "<li>Submit code to a reputable DOI-issuing repository.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Collaboration\n",
    "\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Create an overview of your project.</li>\n",
    "\n",
    "<li>Create a shared \"to-do\" list for the project.</li>\n",
    "\n",
    "<li>Decide on communication strategies.</li>\n",
    "\n",
    "<li>Make the license explicit.</li>\n",
    "\n",
    "<li>Make the project citable.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Project organization\n",
    "\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Put each project in its own directory, which is named after the project.</li>\n",
    "\n",
    "<li>Put text documents associated with the project in the <span class=\"monospace\">doc</span> directory.</li>\n",
    "\n",
    "<li>Put raw data and metadata in a data directory and files generated during cleanup and analysis in a results directory.</li>\n",
    "\n",
    "<li>Put project source code in the <span class=\"monospace\">src</span> directory.</li>\n",
    "\n",
    "<li>Put external scripts or compiled programs in the <span class=\"monospace\">bin</span> directory.</li>\n",
    "\n",
    "<li>Name all files to reflect their content or function.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Keeping track of changes\n",
    "\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Back up (almost) everything created by a human being as soon as it is created.</li>\n",
    "\n",
    "<li>Keep changes small.</li>\n",
    "\n",
    "<li>Share changes frequently.</li>\n",
    "\n",
    "<li>Create, maintain, and use a checklist for saving and sharing changes to the project.</li>\n",
    "\n",
    "<li>Store each project in a folder that is mirrored off the researcher's working machine.</li>\n",
    "\n",
    "<li>Add a file called <span class=\"monospace\">CHANGELOG.txt</span> to the project's <span class=\"monospace\">docs</span> subfolder.</li>\n",
    "\n",
    "<li>Copy the entire project whenever a significant change has been made.</li>\n",
    "\n",
    "<li>Use a version control system.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "<li>Manuscripts\n",
    "\n",
    "\n",
    "<ol class=\"alpha-lower\">\n",
    "\n",
    "<li>Write manuscripts using online tools with rich formatting, change tracking, and reference management.</li>\n",
    "\n",
    "<li>Write the manuscript in a plain text format that permits version control.</li>\n",
    "\n",
    "</ol></li>\n",
    "\n",
    "</ol></div>\n",
    "</div></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3 Ten simple rules for making research software more robust\n",
    "\n",
    "https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1005412\n",
    "\n",
    "What is **“robust”** software? \n",
    "\n",
    "We implied above that it is software that works for people other than the original author and on machines other than its creator’s.\n",
    "\n",
    "More specifically, we mean that:\n",
    "\n",
    "* it can be installed on more than one computer with relative ease,\n",
    "* it works consistently as advertised, and\n",
    "* it can be integrated with other tools.\n",
    "\n",
    "Our rules are generic and can be applied to all languages, libraries, packages, documentation styles, and operating systems for both closed-source and open-source software.\n",
    "\n",
    "1. Use version control\n",
    "\n",
    "2. Document your code and usage\n",
    "\n",
    "3. Make common operations easy to control\n",
    "\n",
    "4. Version your releases\n",
    "\n",
    "5. Reuse software (within reason)\n",
    "\n",
    "6. Rely on build tools and package managers for installation\n",
    "\n",
    "7. Do not require root or other special privileges to install or run\n",
    "\n",
    "8. Eliminate hard-coded paths\n",
    "\n",
    "9. Include a small test set that can be run to ensure the software is actually working\n",
    "\n",
    "10. Produce identical results when given identical inputs\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4  The  Diagrams for  Visual Software Modelling \n",
    "\n",
    "Many diagrams have been proposed over the years for visual software modelling,in order to better understand, maintain, or document information.\n",
    "\n",
    "These diagrams have achieved widespread acceptance:\n",
    " \n",
    "[Flow Chart](https://en.wikipedia.org/wiki/Flowchart)\n",
    "\n",
    "* A flowchart is a type of diagram that represents a workflow or process. A flowchart can also be defined as a diagrammatic representation of an algorithm, a step-by-step approach to solving a task.\n",
    "\n",
    "* The flowchart shows the steps as boxes of various kinds, and their order by connecting the boxes with arrows. This diagrammatic representation illustrates a solution model to a given problem. Flowcharts are used in analyzing, designing, documenting or managing a process or program in various fields\n",
    "\n",
    "[Data Flow Diagrams(DFD)](https://en.wikipedia.org/wiki/Data-flow_diagram)\n",
    "* A data-flow diagram is a way of representing a flow of data through a process or a system (usually an information system). The DFD also provides information about the outputs and inputs of each entity and the process itself. A data-flow diagram has no control flow, there are no decision rules and no loops\n",
    "\n",
    "[Entity-Relationship(E-R) Model Diagrams](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model)\n",
    "* An entity–relationship model (or ER model) describes interrelated things of interest in a specific domain of knowledge. A basic ER model is composed of entity types (which classify the things of interest) and specifies relationships that can exist between entities (instances of those entity types).\n",
    "\n",
    "\n",
    "[Unified Modeling Language(UML) Model diagram](shttps://en.wikipedia.org/wiki/Unified_Modeling_Language)\n",
    "* The Unified Modeling Language (UML) is a general-purpose, developmental, modeling language in the field of software engineering that is intended to provide a standard way to visualize the design of a system\n",
    "* UML 2 has many types of diagrams, which are divided into two categories.Some types represent structural information, and the rest represent general types of behavior, including a few that represent different aspects of interactions. These diagrams can be categorized hierarchically as shown in the following class diagram\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.8.7 64-bit",
   "name": "python387jvsc74a57bd02db524e06e9f5f4ffedc911c917cb75e12dbc923643829bf417064a77eb14d37"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.7"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autoclose": false,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "173.375px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}